<template>
  <div class="logic-flow-container">
    <!-- 指标输出弹窗 -->
    <el-dialog v-model="dialogVisible" title="指标输出" width="80%" :before-close="handleClose">
      <IndicatorOutput
        :indicatorOutputData="dialogData"
        @showCreateIndicator="showCreateIndicatorDialog"
        @goToBack="goToBack"
      />
    </el-dialog>
    <!-- 新建指标弹窗 -->
    <el-dialog
      v-model="createIndicatorVisible"
      title="新建指标"
      width="80%"
      :before-close="closeCreateIndicatorDialog"
    >
      <CreateIndicator
        :createIndicatorData="createIndicatorData"
        @closeCreateIndicator="closeCreateIndicatorDialog"
      />
    </el-dialog>
    <div class="connection_pool">
      <!-- <el-tree-select v-model="id" placeholder="选择连接池" :data="fieldoptions" filterable check-strictly
        :render-after-expand="false" /> -->
      <el-select v-model="dataSourceId" placeholder="请选择连接池" @change="handleChange">
        <el-option
          v-for="item in fieldoptions"
          :key="item.id"
          :label="item.aliasName || item.dataSourceName"
          :value="item.id!"
        />
      </el-select>
      <div class="table_infinite_list" style="overflow: auto">
        <p v-for="item in tableList" class="table_infinite_list_item">
          <el-icon>
            <Coin />
          </el-icon>
          {{ item }}
        </p>
      </div>
    </div>
    <div class="logic-flow-main">
      <div ref="logicFlowRef" class="logic-flow" />
      <Setting
        class="logic-flow-setting"
        :data="nodeData!"
        :lf="lf"
        :type="settingType"
        :parameter="tableListParameter"
        @dataFetched="handleDataFetched"
      />
      <NodePanel :lf="lf" />
    </div>
    <!-- 当lf有值 才能注册事件 -->
    <Control
      v-if="lf"
      :lf="lf"
      :parameter="tableListParameter"
      :dataSourceName="dataSourceName"
      @showIndicatorOutput="showIndicatorOutputDialog"
    />
  </div>
</template>
<script lang="ts">
export default { name: "LogicFlow" };
</script>
<script setup lang="ts">
import LogicFlow from "@logicflow/core";
import "@logicflow/core/lib/style/index.css";
import "@logicflow/extension/lib/style/index.css";
import NodePanel from "./components/nodePanel.vue";
import { registeNode, registerKeyboard } from "./index";
import Control from "./components/control.vue";
import Setting from "./components/setting.vue";
import IndicatorOutput from "./indicatorOutput.vue";
import CreateIndicator from "./createIndicator.vue";
import { SettingType } from "@/types/logic-flow";
import IndicatorManageAPI, {
  DataSourceList,
  TableListParameter,
} from "@/api/strategy/strategy-index-database";
import { useRoute } from "vue-router";

const route = useRoute();

const logicFlowRef = ref<HTMLDivElement>();
const nodeData = ref<LogicFlow.NodeData | LogicFlow.EdgeData>(); // 节点数据
const settingType = ref<SettingType>("all");
// const lf = shallowRef<LogicFlow>();
let lf: LogicFlow;
const dataSourceName = ref<string>();
const dataSourceId = ref<number>();
const fieldoptions = ref<DataSourceList[]>();
const tableListParameter = reactive<TableListParameter>({ id: 0 });
const tableList = ref<string[]>();
const dialogVisible = ref(false);
const dialogData = ref<any>(null);
const createIndicatorVisible = ref(false);
const createIndicatorData = ref<any>(null);

// 处理对话框显示
const showIndicatorOutputDialog = (data: any) => {
  dialogData.value = data;
  dialogVisible.value = true;
};

const showCreateIndicatorDialog = (data: any) => {
  createIndicatorData.value = data;
  createIndicatorVisible.value = true;
};

const goToBack = () => {
  dialogVisible.value = false;
};

// 处理对话框关闭
const handleClose = () => {
  dialogVisible.value = false;
};

const closeCreateIndicatorDialog = () => {
  createIndicatorVisible.value = false;
};
const getSettingInfo = (data: LogicFlow.NodeData | LogicFlow.EdgeData) => {
  switch (data.type) {
    case "all":
      break;
    case "table_input":
      nodeData.value = data;
      settingType.value = data.type;
      break;
    case "sql_input":
      nodeData.value = data;
      settingType.value = data.type;
      break;
    case "left_join":
      nodeData.value = data;
      settingType.value = data.type;
      break;
    case "right_join":
      nodeData.value = data;
      settingType.value = data.type;
      break;
    case "inner_join":
      nodeData.value = data;
      settingType.value = data.type;

    case "full_join":
      nodeData.value = data;
      settingType.value = data.type;

    case "indicator_output":
      nodeData.value = data;
      settingType.value = data.type;
      break;
  }
};

/**
 * @description 注册事件
 */
const initEvent = (lf: LogicFlow) => {
  lf.on("blank:click", (e) => {
    settingType.value = "all";
  });
  lf.on("node:mousedown", ({ data }) => {
    lf.selectElementById(data.id, false);
    getSettingInfo(data);
  });
  lf.on("edge:click", ({ data }) => {
    lf.selectElementById(data.id, false);
    getSettingInfo(data);
  });
  lf.on("connection:not-allowed", (data) => {
    ElMessage.error(data.msg);
    return false;
  });
  lf.on("node:dnd-add", ({ data }) => {
    lf.selectElementById(data.id, false);
    getSettingInfo(data);
    lf.container.focus();
  });
  lf.on("node:change:properties", ({ data }) => {
    if (data.type === "table_input" || data.type === "sql_input") {
      console.log("被触发");
      console.log("-----" + data.id);
      // 获取所有连接到该节点的边
      const edges = lf.graphModel.getNodeIncomingEdge(data.id) || [];
      console.log("....." + edges);
      edges.forEach((edge: { targetNodeId: any }) => {
        const targetNode = lf.graphModel.getNodeById(edge.targetNodeId);
        if (targetNode?.type.includes("_join") || targetNode?.type === "indicator_output") {
          console.log("开始传输数据");
          transferData(data, targetNode); // 实时传输数据
        }
      });
    }
  });
  lf.on("edge:add", ({ data }) => {
    if (!lf.graphModel) {
      console.error("lf.graphModel is undefined");
      return;
    }
    const sourceNode = lf.graphModel.getNodeById
      ? lf.graphModel.getNodeById(data.sourceNodeId)
      : lf.graphModel.nodeModelMap.get(data.sourceNodeId);

    const targetNode = lf.graphModel.getNodeById
      ? lf.graphModel.getNodeById(data.targetNodeId)
      : lf.graphModel.nodeModelMap.get(data.targetNodeId);

    if (!sourceNode || !targetNode) {
      console.error("Source or Target Node not found:", data);
      return;
    }

    const validTargetTypes = [
      "left_join",
      "right_join",
      "inner_join",
      "full_join",
      "indicator_output",
    ];
    if (sourceNode && targetNode) {
      if (validTargetTypes.includes(targetNode.type)) {
        transferData(sourceNode, targetNode);
        // 监听源节点的数据变化
        watch(
          () =>
            sourceNode.getProperties().tableData ||
            sourceNode.getProperties.related_fields1 ||
            sourceNode.getProperties.related_fields2,
          (newData: any) => {
            console.log("Source node tableData has changed:", newData);
            transferData(sourceNode, targetNode);
          },
          {
            deep: true,
          }
        );
      }
    }
  });
};

const transferData = (sourceNode: any, targetNode: any) => {
  // 获取 sourceNode 的数据
  const sourceProperties = sourceNode.getProperties();
  // 获取 targetNode 的现有数据
  const targetProperties = targetNode.getProperties();
  const validTargetTypes = ["left_join", "right_join", "inner_join", "full_join"];
  // 新增：如果源节点是 left_join 节点，获取拼接好的 related_fields1 和 related_fields2
  if (validTargetTypes.includes(sourceNode.type)) {
    const joinConnectedData = sourceProperties.joinConnectedData;
    const connectedData = targetProperties.joinConnectedData || []; //如果connectedData为undefined，初始化为空数组
    let newConnectedData = Array.isArray(connectedData) ? connectedData : [connectedData];
    const index = newConnectedData.findIndex((item) => item.propsDataId === sourceNode.id);
    if (index !== -1) {
      newConnectedData[index] = joinConnectedData;
    } else {
      newConnectedData.push(joinConnectedData);
    }
    targetNode.setProperties({
      ...targetProperties,
      joinConnectedData: newConnectedData,
    });
    targetNode.setProperties({
      ...targetProperties,
      joinConnectedData: newConnectedData,
    });
  }
  if (sourceNode.type == "sql_input") {
    const sourceTableName = sourceProperties.tableName;
    const sourceData = sourceProperties.tableData;
    const connectedData = targetProperties.connectedData || []; // 如果 connectedData 为 undefined，初始化为空数组
    const newConnectedData = connectedData.map((item: any) => {
      if (item.tableName === sourceTableName._value) {
        return {
          tableName: sourceTableName._value,
          data: sourceData._value,
        };
      }
      return item;
    });
    // 如果没有对应的数据，则添加新数据
    if (!newConnectedData.some((item: any) => item.tableName === sourceTableName._value)) {
      console.log("源表名称不相同！！！！");
      newConnectedData.push({
        tableName: sourceTableName._value,
        data: sourceData._value,
      });
    }
    // 更新 targetNode 的属性
    targetNode.setProperties({
      ...targetProperties,
      connectedData: newConnectedData,
    });
  }
  if (sourceNode.type == "table_input") {
    const sourceTableName = sourceProperties.tableName;
    const sourceData = sourceProperties.tableData.filter((row: any) => row.isSelected);
    // 将 sourceData 覆盖 targetNode 的对应数据
    const connectedData = targetProperties.connectedData || []; // 如果 connectedData 为 undefined，初始化为空数组
    const newConnectedData = connectedData.map((item: any) => {
      if (item.tableName === sourceTableName) {
        return {
          tableName: sourceTableName,
          data: sourceData,
        };
      }
      return item;
    });
    const existingIndex = newConnectedData.findIndex(
      (item: any) => item.tableName === sourceTableName
    );
    const updatedData = {
      tableName: sourceTableName,
      data: sourceData,
    };
    if (existingIndex !== -1) {
      newConnectedData[existingIndex] = updatedData;
    } else {
      newConnectedData.push(updatedData);
    }

    // 更新 targetNode 的属性
    targetNode.setProperties({
      ...targetProperties,
      connectedData: newConnectedData,
    });
  }
};

const handleDataFetched = (data: any) => {
  console.log(data);
};

async function handleQuery() {
  fieldoptions.value = await IndicatorManageAPI.DataSourceList();
}

async function handleChange(id: number) {
  tableListParameter.id = id;
  dataSourceName.value = fieldoptions.value.find((item) => item.id === id)?.aliasName || "";
  tableList.value = await IndicatorManageAPI.TableList(tableListParameter);
}

onMounted(() => {
  lf = new LogicFlow({
    container: logicFlowRef.value!,
    grid: true,
    keyboard: {
      enabled: true,
      shortcuts: registerKeyboard(lf, nodeData, settingType),
    },
    textEdit: false,
    // 尝试添加 passive 选项配置
    events: {
      touchmove: {
        passive: false,
      },
      wheel: {
        passive: false,
      },
    },
  });
  handleQuery().then(() => {
    // 获取路由参数中的数据源id
    dataSourceId.value = route.query.dataSourceId;
    if (dataSourceId.value) {
      // 设置数据源id
      dataSourceName.value =
        fieldoptions.value.find((item) => item.id === Number(dataSourceId.value))?.aliasName || "";
      // 调用handleChange加载表列表
      handleChange(Number(dataSourceId.value));
    }
  });
  registeNode(lf);
  initEvent(lf);
  lf.render({});
  lf.translateCenter();
  localStorage.removeItem("previousExtractedData");
});
</script>
<style lang="scss" scoped>
.logic-flow-container {
  display: flex;
  width: 100%;
  height: 100%;

  .connection_pool {
    width: 15%;
    // height: calc(100% - 54px);
    height: calc(100% - 0px);

    .table_infinite_list {
      height: calc(100% - 20px);
      padding: 0;
      margin: 0;
      list-style: none;
    }

    .table_infinite_list .table_infinite_list_item {
      display: flex;
      gap: 8px;
      align-items: center;
      justify-content: flex-start;
      height: 20px;
      margin: 10px;
    }

    .table_infinite_list .table_infinite_list_item + .list-item {
      margin-top: 10px;
    }
  }

  .logic-flow-header {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    height: 50px;
    padding: 0 20px;
    border-bottom: 1px solid #ccc;
  }

  .logic-flow-main {
    position: relative;
    display: flex;
    width: 85%;
    // height: calc(100% - 54px);
    height: calc(100% - 0px);

    .logic-flow-setting {
      flex-shrink: 0;
      flex-basis: 400px;
      border-left: 1px solid #ccc;
    }

    .logic-flow {
      position: relative;
      flex: 1;
      height: 100%;
    }
  }
}
</style>
